﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using ProTrack.Api.Helper;
using ProTrack.Dto;
using ProTrack.IServices;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace ProTrack.Api.Controllers
{

    /// <summary>
    /// 账户服务接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        public AccountController(IAccountServices accountServices,IConfiguration Configuration, LogHelper LogHelper)
        {
            AccountServices = accountServices;
            _configuration = Configuration;
            this.LogHelper = LogHelper;
        }

        public IAccountServices AccountServices { get; }
        public IConfiguration _configuration { get; }
        public LogHelper LogHelper { get; }


        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="UserName">用户名</param>
        /// <param name="PassWord">密码</param>
        /// <returns></returns>
        [HttpGet, AllowAnonymous]
        public async Task<IActionResult> Login([FromQuery] string UserName, [FromQuery] string PassWord)
        {

            var status = BaseStatus.CreateInstance();

            try
            {
                var isSuccess = await AccountServices.Signin(UserName, PassWord);
                if (isSuccess)
                {
                    //定义用户策略
                    var claims = new[] {
                        new Claim(ClaimTypes.Name,UserName),
                        //配置过期时间
                        new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                        new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}")

                    };
                    //秘钥
                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
                    //签名
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    var token = new JwtSecurityToken(
                        issuer: "MESAdmin",//jwt签发者
                        audience:UserName,//jwt的接收该方
                        claims: claims,
                        expires: DateTime.Now.AddMinutes(30),//到期时间
                        signingCredentials: creds);
                    //请求格式 Header添加 : Authorization : Bearer 秘钥


                    status.Data = new JwtSecurityTokenHandler().WriteToken(token);
                    status.Msg="登录成功";
                }
                else
                {
                    status.Code = -1;
                    status.Msg = "登录失败，账户名或密码有误！";
                }
            }
            catch (Exception ex)
            {
                status.Code = -1;
                status.Msg = "登录失败，服务器异常，请稍后再试！";


                //写日志
                await LogHelper.WriteErrorLog("登录模块",ex,HttpContext);
            }
            return new JsonResult(status);
        }
        

        /// <summary>
        /// 获取图片验证码（130×40）【无需凭证】
        /// </summary>
        /// <param name="code">随机数字</param>
        /// <returns>图片流格式：image/jpeg</returns>
        [HttpGet, AllowAnonymous, Route("GetVerifyCode")]
        public IActionResult GetVerifyCode(string code)
        {
            //实例化图片对象
            Bitmap image = DrawImage(code);
            try
            {
                //保存图片到内存中  返回字节数组
                using (MemoryStream stream = new MemoryStream())
                {
                    image.Save(stream, ImageFormat.Jpeg);
                    return File(stream.ToArray(), @"image/jpeg");
                }
            }
            catch (Exception ex)
            {
                //捕获日志
                return new JsonResult(BaseStatus.CreateInstance(-1,"生成验证码失败"));
            }
        }
        private static Bitmap DrawImage(string code)
        {
            Color[] colors = {
                Color.Red, Color.OrangeRed,Color.SaddleBrown,
                Color.LimeGreen,Color.Green,Color.MediumAquamarine,
                Color.Blue,Color.MediumOrchid,Color.Black,
                Color.DarkBlue,Color.Orange,Color.Brown,
                Color.DarkCyan,Color.Purple
            };
            string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
            Random random = new Random();
            // 创建一个 Bitmap 图片类型对象
            Bitmap bitmap = new Bitmap(130, 40);
            // 创建一个图形画笔
            Graphics graphics = Graphics.FromImage(bitmap);
            // 将图片背景填充成白色
            graphics.Clear(Color.White);
            // 绘制验证码噪点
            for (int i = 0; i < random.Next(60, 80); i++)
            {
                int pointX = random.Next(bitmap.Width);
                int pointY = random.Next(bitmap.Height);
                graphics.DrawLine(new Pen(Color.LightGray, 1), pointX, pointY, pointX + 1, pointY);
            }
            // 绘制随机线条 1 条
            graphics.DrawLine(
                    new Pen(colors[random.Next(colors.Length)], random.Next(3)),
                    new Point(
                        random.Next(bitmap.Width),
                        random.Next(bitmap.Height)),
                    new Point(random.Next(bitmap.Width),
                    random.Next(bitmap.Height)));
            // 绘制验证码
            for (int i = 0; i < code.Length; i++)
            {
                graphics.DrawString(
                    code.Substring(i, 1),
                    new Font(fonts[random.Next(fonts.Length)], 25, FontStyle.Bold),
                    new SolidBrush(colors[random.Next(colors.Length)]),
                    25 * i + 6,
                    random.Next(0, 4)
                    );
            }
            // 绘制验证码噪点
            for (int i = 0; i < random.Next(30, 50); i++)
            {
                int pointX = random.Next(bitmap.Width);
                int pointY = random.Next(bitmap.Height);
                graphics.DrawLine(new Pen(colors[random.Next(colors.Length)], 1), pointX, pointY, pointX, pointY + 1);
            }
            // 绘制随机线条 1 条
            graphics.DrawLine(
                    new Pen(colors[random.Next(colors.Length)], random.Next(3)),
                    new Point(
                        random.Next(bitmap.Width),
                        random.Next(bitmap.Height)),
                    new Point(random.Next(bitmap.Width),
                    random.Next(bitmap.Height)));
            return bitmap;
        }
    }
}
